
package com.x52im.rbchat.logic.chat_friend.vv;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.eva.android.NewAsyncTask;
import com.eva.android.widget.DataLoadableActivity;
import com.eva.android.DelayedHandler;
import com.eva.android.ObserverMain;
import com.eva.android.widget.WidgetUtils;
import com.eva.android.widget.WidgetUtils.ToastType;
import com.eva.android.x.XToolKits;
import com.eva.framework.dto.DataFromServer;
import com.vc.core.VcConstants;
import com.x52im.rbchat.MyApplication;
import com.x52im.rbchat.R;
import com.x52im.rbchat.cache.ImageCacheLoader;
import com.x52im.rainbowchat.http.logic.dto.RosterElementEntity;
import com.x52im.rbchat.logic.chat_friend.utils.MessageHelper;
import com.x52im.rbchat.logic.chat_root.model.VoipRecordMeta;
import com.x52im.rbchat.logic.qrcode.utils.StatusBarUtils;
import com.x52im.rbchat.utils.PromtHelper;
import com.x52im.rbchat.utils.IntentFactory;
import com.x52im.rbchat.network.im.ChatMessageEventListener;

import net.x52im.rainbowav.sdk.iface.IReceiveEventListener;

import java.text.MessageFormat;
import java.util.Observable;

/**
 * 音视频聊天请求呼入处理Activity.
 * 
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @version 1.0
 */
public class VideoCallOutActivity extends DataLoadableActivity 
{
	private final static String TAG = VideoCallOutActivity.class.getSimpleName();
	
	/** 文本组件：好友昵称 */
	private TextView viewFriendNickName = null;
	/** 文本组件：提示文本 */
	private TextView viewHint = null;
	/** 按钮：结束 */
	private View btnEnd = null;
	/** 好友头像 */
	private ImageView viewAvatar = null;
	
	private MediaPlayer promtMp = null;
	
	// 暂存从Intent中传过来的好友信息数据（将要用于界面展现）:
	private String friendUIDForInit = null; 
	
	/** 
	 * 音视频聊天呼出事件观察者（本观察者将在{@link ChatMessageEventListener}
	 * 收到对方（视频聊天接收方）的“同意”或“不同意”的处理时被通知）. */
	private ObserverMain videoCallOutObserver = new ObserverMain(){
		@Override
		public void updateInMain(Observable observable, Object data) {
			int responseCode = (Integer)data;
			// 对方拒绝了我
			if(responseCode == 0) {
				showHint($$(R.string.video_call_out_invite_refused), true);
				WidgetUtils.showToast(VideoCallOutActivity.this, $$(R.string.video_call_out_invite_refused), ToastType.INFO);
				
			}
			// 对方同意了视频聊天哦
			else if(responseCode == 1) {
				Log.d(TAG, "好友同意了你的视频请求！");
				VVP2PProvider.acceptRequest(VideoCallOutActivity.this, 2, Long.parseLong(friendUIDForInit), imc().getFriendsListProvider().getFriendInfoByUid2(friendUIDForInit).getNickname());
			} else {
				WidgetUtils.showToast(self(), MessageFormat.format($$(R.string.video_call_out_respone_unkown), responseCode));
			}

			finishNotSendReject();
		}
	};
	
	// 超时处理Handler
	private DelayedHandler delayedHandler = new DelayedHandler(VoiceCallOutDialog.DEFAULT_CALLING_TIMEOUT){
		@Override
		protected void fireRun() {
			// 发出一条音视频聊天记录（这样的话，本地和远端都会有记录的哟）
			MessageHelper.sendVoipRecordMessageAsync(
					// context用全局Application对象，确保消息的发送不依赖于本Activity的生命周期
					MyApplication.getInstance2()
					, friendUIDForInit
					, new VoipRecordMeta(VoipRecordMeta.VOIP_TYPE_VIDEO, VoipRecordMeta.RECORD_TYPE_CALLING_TIMEOUT)
					, null);

			WidgetUtils.showToastLong(VideoCallOutActivity.this, $$(R.string.video_call_out_invite_time_out), ToastType.WARN);
			finishNotSendReject();
		}
	};
	
	private NewVVReceiveEventListener newVVReceiveEventListener = null;

	/**
	 * Called when the activity is first created.
	 */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		// 全面屏沉浸式效果（系统顶部状态栏将变的透明，界面从状态栏下方透过）
		XToolKits.setStatusBarTranslucent(this, true);
		// 全面屏沉浸式效果（系统底部导航栏将变的透明，界面从导航栏下方透过）
		XToolKits.setNavigationBarTranslucent(this, true);
		super.onCreate(savedInstanceState);
	}

	protected void onResume() {
		imc().getTransDataListener().setVideoCallOutObserver(videoCallOutObserver);
		if(newVVReceiveEventListener != null)
			newVVReceiveEventListener.setBack(false);
		super.onResume();
	}

	protected void onPause() {
		imc().getTransDataListener().setVideoCallOutObserver(null);
		if(newVVReceiveEventListener != null)
			newVVReceiveEventListener.setBack(true);
		super.onPause();
	}

	/**
	 * 重写父类方法，取消深色状态栏文字的设置。
	 */
	@Override
	protected void configStatusBarTextColorDark()
	{
		// 什么也不需要做
	}
	
	public void finishNotSendReject() {
		_finish(true);
		super.finish();
	}
	
	@Override 
	public void finish() {
		_finish(false);
		super.finish();
	}
	
	public void _finish(boolean finishNotSendReject) {
		VVP2PProvider.getInstance(this).getP2PController().unRegistryRequestEventListener(newVVReceiveEventListener);
	
		if(delayedHandler != null) {
			delayedHandler.stop();
			delayedHandler = null;
		}
		
		try {
			if(promtMp != null)
				promtMp.stop();
		} catch (Exception e) {
		    Log.w(TAG, e);
		}
		
		if(!finishNotSendReject)
			fireEndCall();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void initDataFromIntent() {
		// 解析从intent中传过来的数据：
		friendUIDForInit = IntentFactory.parseVideoCallOutIntent(getIntent());
	}
	
	/**
	 * 本方法由父类的onCreate()调用，子类可在此方法中实现自已的UI显示逻辑。
	 */
	@Override
	protected void initViews(Bundle savedInstanceState) {
		//养成良好习惯：首先设置主layout，确保后绪的操作中使用到的组件都可以被find到
		setContentView(R.layout.video_call_out_activity_v9);
		
		this.setTitle($$(R.string.video_call_out_inviting));

//		// 对界面上方进行全面屏设置
//		StatusBarUtils.immersiveStatusBar(this, findViewById(R.id.toolbar),0.2f);
		
		//** 
		viewFriendNickName = (TextView)findViewById(R.id.video_call_out_friendNickNameView);
		viewHint = (TextView)findViewById(R.id.video_call_out_hintView);
		btnEnd = (View)findViewById(R.id.video_call_out_endBtn);
		viewAvatar = (ImageView)this.findViewById(R.id.voipcall_avatarView);

		//** 对方的好友信息
		RosterElementEntity friendInfo = imc().getFriendsListProvider().getFriendInfoByUid2(friendUIDForInit);
		// ** 显示头像和昵称
		if(friendInfo != null) {
			ImageCacheLoader.loadAvatarImgWithGlide(this, friendInfo.getUser_uid(), friendInfo.getUserAvatarFileName()
					, viewAvatar, 60, R.drawable.default_avatar_yuan_100_3x, true, false);
			viewFriendNickName.setText(friendInfo.getNickname());// 25
		}
		
		//** 注册P2P事件监听
		newVVReceiveEventListener = new NewVVReceiveEventListener(this);
		VVP2PProvider.getInstance(this).getP2PController().registryRequestEventListener(newVVReceiveEventListener);
//		//** P2P打洞请求（首先尝试P2P打洞哦）
//		VVP2PProvider.getInstance(this).requestP2P(Long.parseLong(friendUIDForInit));
		//** 
		promtMp = PromtHelper.callingPromt(this, friendUIDForInit);
		//** 发出聊天请求
		sendRequest();

		this.setLoadDataOnCreate(false);
	}
	
	public void showHint(String text, boolean playEndPrompt) {
		if(playEndPrompt)
			// 播放提示音
			PromtHelper.playendPromt(VideoCallOutActivity.this);
		viewHint.setText(text);
	}
	
	private void sendRequest() {
		// 新聊天框架中的网络数据发送需要放到异步线程里（Android2.3以上版本要求网络交互不允许发生在主线程里）
		new AsyncTask<Object, Integer, Integer>(){
			@Override
			protected Integer doInBackground(Object... params) {
				RosterElementEntity friendERR = imc().getFriendsListProvider().getFriendInfoByUid2(friendUIDForInit);
				int code = MessageHelper.sendVideoAndVoiceRequest$Requestting_from$a(self(), friendERR.getUser_uid(), imc().getLocalUserInfo().getUser_uid());
				return code;
			}

			@Override
			protected void onPostExecute(Integer code) {
				if(code == 0) {
					showHint($$(R.string.video_call_out_wait_respone), false);
				} else {
					showHint($$(R.string.video_call_out_send_invite_failure), false);
					WidgetUtils.showToast(self(), $$(R.string.video_call_out_send_invite_failure), ToastType.WARN);
					finishNotSendReject();
				}
			}
		}.execute();
	}
	
	private void fireEndCall() {
		// 新聊天框架中的网络数据发送需要放到异步线程里（Android2.3以上版本要求网络交互不允许发生在主线程里）
		new NewAsyncTask<Object, Integer, Integer>(){
			@Override
			protected Integer doInBackground(Object... params) {
				RosterElementEntity friendERR = imc().getFriendsListProvider().getFriendInfoByUid2(friendUIDForInit);
				int code = MessageHelper.sendVideoAndVoiceRequest$Abort_from$a(self(), friendERR.getUser_uid(), imc().getLocalUserInfo().getUser_uid());
				return code;
			}

			@Override
			protected void onPostExecute(Integer code) {
				if(code == 0) {
					showHint($$(R.string.video_call_out_cancle_invite), false);

					// 发出一条音视频聊天记录（这样的话，本地和远端都会有记录的哟）
					MessageHelper.sendVoipRecordMessageAsync(
							// context用全局Application对象，确保消息的发送不依赖于本Activity的生命周期
							MyApplication.getInstance2()
							, friendUIDForInit
							, new VoipRecordMeta(VoipRecordMeta.VOIP_TYPE_VIDEO, VoipRecordMeta.RECORD_TYPE_REQUEST_CANCEL)
							, null);
				} else {
					Log.w(VideoCallOutActivity.class.getSimpleName(), $$(R.string.video_call_out_send_cancle_failure));
					WidgetUtils.showToast(VideoCallOutActivity.this, $$(R.string.video_call_out_send_cancle_failure), ToastType.WARN);
				}
			}
		}.execute();
	}
	
	/**
	 * 本方法由父类的onCreate()调用，子类可在此方法中为各UI功能组件增加事件临听。
	 */
	@Override
	protected void initListeners() {
		btnEnd.setOnClickListener(v -> finish());
	}
	
	@Override
	protected DataFromServer queryData(String... arg0) {
		return null;
	}

	@Override
	protected void refreshToView(Object arg0) {
	}


	public static class NewVVReceiveEventListener implements IReceiveEventListener {
		private boolean isBack = false;
		private Activity activity = null;
		private Handler handler = null;
	    
	    public NewVVReceiveEventListener(final Activity activity) {
	    	this.activity = activity;
	    	this.handler = new Handler(){
		        @Override
		        public void handleMessage(Message msg) {
		            Bundle data = msg.getData();
		            long fromAccount = data.getLong("fromAccount",0);
		            switch(msg.what){
		                //p2p打洞成功
			            case VcConstants.TYPE_CONNECT_P2P_SUCC:
		                    Log.d(TAG, "DEBUG: 与对方p2p连接成功!");
		                    break;
		                //p2p连接失败/断开
			            case VcConstants.TYPE_CONNECT_P2P_FAILED:
			            	Log.d(TAG, "DEBUG: 与对方p2p连接失败!");
		                    //finish();
		                    break;
		            }
		        }
		    };
	    }
		
		@Override
		public void onReceiveEvent(int eventId, long fromAccount, byte[] detail) {
			if(!isBack) {
	            Message msg = new Message();
	            msg.what = eventId;
	            Bundle bundle = new Bundle();
	            bundle.putLong("fromAccount",fromAccount);
	            bundle.putByteArray("detail",detail);
	            msg.setData(bundle);
	            handler.sendMessage(msg);
	        }
		}

		public void setBack(boolean isBack) {
			this.isBack = isBack;
		}
	}
}
